﻿#pragma once
#include "yzrutil.h"
#include "DSP.h"
#include "RingBuffer.h"
#include "array/Array.hpp"

namespace yzrilyzr_dsp{
	ECLASS(FIR, public DSP){
	public:
	yzrilyzr_array::SampleArray coeff;
	RingBufferSample * x=nullptr;
	FIR(){}
	FIR(yzrilyzr_array::SampleArray coeff){
		this->coeff=coeff;
		this->x=new RingBufferSample(coeff.length);
	}
	FIR(u_index coeffLen):FIR(yzrilyzr_array::SampleArray(coeffLen)){}
	~FIR(){
		delete x;
	}
	u_sample procDsp(u_sample v)override{
		u_sample con=0;
		yzrilyzr_array::SampleArray & c=coeff;
		u_index cL=c.length;
		for(u_index i=0;i < cL;++i){
			con+=x->getFromOldest((int32_t)i) * c[i];
		}
		x->write(v);//产生了延迟
		return con;
	}
	void init(u_sample_rate sampleRate)override{}
	void resetMemory()override{
		x->fill(0);
	}
	std::shared_ptr<DSP> cloneDSP()override{
		return std::make_shared < FIR>(coeff.clone());
	}
	void setCoeff(yzrilyzr_array::SampleArray  coeff){
		this->coeff=coeff;
		if(x == nullptr || x->capacity() != coeff.length){
			delete x;
			x=new RingBufferSample(coeff.length);
		}
	}
	void cloneParam(DSP * obj1)override{
		if(auto other=dynamic_cast<FIR *>(obj1)){
			yzrilyzr_array::SampleArray & c=coeff;
			u_index cL=c.length;
			for(u_index i=0;i < cL;++i){
				c[i]=(other->coeff)[i];
			}
		}
	}
	yzrilyzr_lang::String toString()const override;
	};
}